package com.java.jvm.loader;

import java.io.*;

/**
 * ClassLoader没有抽象方法为什么还要将此类定义为抽象类？
 * 外界不允许直接构建此类对象
 */
public class SimpleAppClassLoader extends ClassLoader{
    private String baseDir;
    public SimpleAppClassLoader(String baseDir){//base=D:/aaa/bbb/ccc/pkg/Hello.class
        this.baseDir=baseDir;
    }

    /**
     * findClass 方法用户查找类，并读取类的信息，然后创建一个字节码对象。
     * @param className
     * @return
     * @throws ClassNotFoundException
     */
    //className=pkg.Hello
    @Override
    protected Class<?> findClass(String className) throws ClassNotFoundException {
        //1.获取className实际的物理位置 (com/java/Hello)
        String classFilePath=baseDir+className.replace(".", File.separator)+".class";
        //2.判定此位置的className文件是否存在
        File file=new File(classFilePath);
        if(!file.exists())
            throw new ClassNotFoundException();
        //3.读取class文件
        InputStream in=null;
        byte[] data=null;
        try {
            in=new FileInputStream(file);//所谓类加载还是要通过io去读取类文件的。
            data=new byte[in.available()];//in.available()获取流中的有效字节数
            in.read(data);
         //4.构建字节码对象(不要重写defineClass方法，此方法是基于数组创建Class对象)
            return defineClass(className, data, 0, data.length);
        } catch (IOException e) {
            e.printStackTrace();
            throw new RuntimeException(e);
        }finally{
            if(in!=null) { try { in.close(); } catch (IOException e) { e.printStackTrace(); } }
        }
    }
}
